package org.light.shiroauth;

import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import org.light.domain.Domain;
import org.light.domain.Dropdown;
import org.light.domain.Field;
import org.light.domain.Statement;
import org.light.domain.StatementList;
import org.light.domain.Util;

public class UserRealmGenerator extends Util{
	protected Domain userDomain;
	protected Domain roleDomain;
	protected Domain privilegeDomain;
	
	public UserRealmGenerator(){
		super();
		super.fileName = "UserRealm.java";
	}
	
	public UserRealmGenerator(String packageToken){
		super();
		this.setPackageToken(packageToken);
		super.fileName = "UserRealm.java";
	}
	
	@Override
	public void setPackageToken(String packageToken) {
		this.packageToken = packageToken;
	}
	
	@Override
	public String generateUtilString() {
		StatementList sList = new StatementList();
		sList.add(new Statement(500L,"package "+this.getPackageToken()+".shiro;"));
		sList.add(new Statement(3000L,0,""));
		sList.add(new Statement(4000L,0,"import java.util.HashSet;"));
		sList.add(new Statement(5000L,0,"import java.util.Set;"));
		
		sList.add(new Statement(5100L,0,"import java.util.ArrayList;"));
		sList.add(new Statement(5200L,0,"import java.util.List;"));
		
		sList.add(new Statement(6000L,0,""));
		sList.add(new Statement(7000L,0,"import javax.servlet.http.HttpSession;"));
		sList.add(new Statement(8000L,0,""));
		sList.add(new Statement(9000L,0,"import org.apache.shiro.SecurityUtils;"));
		sList.add(new Statement(10000L,0,"import org.apache.shiro.authc.AuthenticationException;"));
		sList.add(new Statement(11000L,0,"import org.apache.shiro.authc.AuthenticationInfo;"));
		sList.add(new Statement(12000L,0,"import org.apache.shiro.authc.AuthenticationToken;"));
		sList.add(new Statement(13000L,0,"import org.apache.shiro.authc.SimpleAuthenticationInfo;"));
		sList.add(new Statement(14000L,0,"import org.apache.shiro.authc.UsernamePasswordToken;"));
		sList.add(new Statement(15000L,0,"import org.apache.shiro.authz.AuthorizationInfo;"));
		sList.add(new Statement(16000L,0,"import org.apache.shiro.authz.SimpleAuthorizationInfo;"));
		sList.add(new Statement(17000L,0,"import org.apache.shiro.realm.AuthorizingRealm;"));
		sList.add(new Statement(18000L,0,"import org.apache.shiro.subject.PrincipalCollection;"));
		sList.add(new Statement(19000L,0,"import org.apache.shiro.subject.Subject;"));
		sList.add(new Statement(20000L,0,"import org.springframework.beans.factory.annotation.Autowired;"));
		sList.add(new Statement(21000L,0,"import org.springframework.web.context.request.RequestContextHolder;"));
		sList.add(new Statement(22000L,0,"import org.springframework.web.context.request.ServletRequestAttributes;"));
		sList.add(new Statement(23000L,0,""));

		sList.add(new Statement(24000L,0,"import "+this.userDomain.getPackageToken()+"."+this.userDomain.getDomainSuffix()+"."+this.userDomain.getCapFirstDomainNameWithSuffix()+";"));
		sList.add(new Statement(25000L,0,"import "+this.userDomain.getPackageToken()+"."+this.userDomain.getServiceSuffix()+"."+this.userDomain.getCapFirstDomainName()+"Service;"));

		sList.add(new Statement(25100L,0,"import "+this.roleDomain.getPackageToken()+"."+this.roleDomain.getDomainSuffix()+"."+this.roleDomain.getCapFirstDomainNameWithSuffix()+";"));
		sList.add(new Statement(25200L,0,"import "+this.roleDomain.getPackageToken()+"."+this.roleDomain.getServiceSuffix()+"."+this.roleDomain.getCapFirstDomainName()+"Service;"));
		sList.add(new Statement(25300L,0,"import "+this.privilegeDomain.getPackageToken()+"."+this.privilegeDomain.getDomainSuffix()+"."+this.privilegeDomain.getCapFirstDomainNameWithSuffix()+";"));	
		
		sList.add(new Statement(26000L,0,""));
		sList.add(new Statement(27000L,0,"public class UserRealm extends AuthorizingRealm"));
		sList.add(new Statement(28000L,0,"{"));
		sList.add(new Statement(29000L,1,"@Autowired"));
		sList.add(new Statement(30000L,1,"private "+this.userDomain.getCapFirstDomainName()+"Service "+this.userDomain.getLowerFirstDomainName()+"Service;"));
		sList.add(new Statement(31000L,0,""));
		sList.add(new Statement(31100L,1,"@Autowired"));
		sList.add(new Statement(31200L,1,"private "+this.roleDomain.getCapFirstDomainName()+"Service "+this.roleDomain.getLowerFirstDomainName()+"Service;"));
		sList.add(new Statement(31300L,0,""));
		sList.add(new Statement(32000L,1,"/**"));
		sList.add(new Statement(33000L,1,"* 执行认证逻辑"));
		sList.add(new Statement(34000L,1,"* @param authenticationToken"));
		sList.add(new Statement(35000L,1,"* @return"));
		sList.add(new Statement(36000L,1,"* @throws AuthenticationException"));
		sList.add(new Statement(37000L,1,"*/"));
		sList.add(new Statement(38000L,1,"@Override"));
		sList.add(new Statement(39000L,1,"protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException"));
		sList.add(new Statement(40000L,1,"{"));
		sList.add(new Statement(41000L,2,"try {"));
		sList.add(new Statement(42000L,2,"UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken; //获得用户输入的用户名,这个对象就是login()传递过来的，将它强转以取出封装的用户名"));
		sList.add(new Statement(43000L,2,"String userNameInput = token.getUsername();"));
		sList.add(new Statement(44000L,0,""));
		sList.add(new Statement(45000L,2,this.userDomain.getCapFirstDomainNameWithSuffix()+" selectUser = "+this.userDomain.getLowerFirstDomainName()+"Service.find"+this.userDomain.getCapFirstDomainName()+"By"+this.userDomain.getDomainName().getCapFirstFieldName()+"(userNameInput);"));
		sList.add(new Statement(46000L,2,"String encPassowrd = "+this.userDomain.getLowerFirstDomainName()+"Service.getPassword"+this.userDomain.getCapFirstDomainName()+"(userNameInput);"));
		sList.add(new Statement(47000L,2,"if(selectUser == null) //用户不存在，返回null"));
		sList.add(new Statement(48000L,2,"{"));
		sList.add(new Statement(49000L,3,"return null;"));
		sList.add(new Statement(50000L,2,"}"));
		sList.add(new Statement(51000L,0,""));
		sList.add(new Statement(52000L,2,"return new SimpleAuthenticationInfo(selectUser, encPassowrd, \"\");"));
		sList.add(new Statement(53000L,2,"}catch (Exception e) {"));
		sList.add(new Statement(54000L,3,"e.printStackTrace();"));
		sList.add(new Statement(55000L,3,"throw new AuthenticationException();"));
		sList.add(new Statement(56000L,2,"}"));
		sList.add(new Statement(57000L,1,"}"));
		sList.add(new Statement(58000L,0,""));
		sList.add(new Statement(59000L,1,"/**"));
		sList.add(new Statement(60000L,1,"* 执行授权逻辑"));
		sList.add(new Statement(61000L,1,"* @param principalCollection"));
		sList.add(new Statement(62000L,1,"* @return"));
		sList.add(new Statement(63000L,1,"*/"));
		sList.add(new Statement(64000L,1,"@Override"));
		sList.add(new Statement(65000L,1,"protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection)"));
		sList.add(new Statement(66000L,1,"{"));
		
		sList.add(new Statement(66000L,2,"try {"));
		
		sList.add(new Statement(67000L,3,"Subject subject = SecurityUtils.getSubject(); //获得一个Subject对象"));
		sList.add(new Statement(68000L,3,this.userDomain.getCapFirstDomainNameWithSuffix()+" "+this.userDomain.getLowerFirstDomainName()+" = ("+this.userDomain.getCapFirstDomainNameWithSuffix()+") subject.getPrincipal(); //获得登录的对象"));
		sList.add(new Statement(69000L,3,"Set<String> "+this.roleDomain.getLowerFirstDomainName()+"Names=new HashSet<String>();"));
		
		sList.add(new Statement(74000L,3,"List<String> "+this.privilegeDomain.getLowerFirstDomainName()+"NameList=new ArrayList<String>();"));
		sList.add(new Statement(75000L,3,""));

		sList.add(new Statement(77000L,3,"Set<"+this.roleDomain.getCapFirstDomainNameWithSuffix()+"> "+this.roleDomain.getLowerFirstPlural()+" = "+this.userDomain.getLowerFirstDomainName()+"Service.listActive"+this.userDomain.getCapFirstDomainName()+this.roleDomain.getCapFirstPlural()+"Using"+this.userDomain.getCapFirstDomainName()+"Id("+this.userDomain.getLowerFirstDomainName()+".get"+this.userDomain.getDomainId().getCapFirstFieldName()+"());"));
		sList.add(new Statement(78000L,3,"for("+this.roleDomain.getCapFirstDomainNameWithSuffix()+" "+this.roleDomain.getLowerFirstDomainName()+":"+this.roleDomain.getLowerFirstPlural()+"){"));
		sList.add(new Statement(79000L,4,""+this.roleDomain.getLowerFirstDomainName()+"Names.add("+this.roleDomain.getLowerFirstDomainName()+".get"+this.roleDomain.getDomainName().getCapFirstFieldName()+"());"));
		sList.add(new Statement(80000L,4,"Set<"+this.privilegeDomain.getCapFirstDomainNameWithSuffix()+"> "+this.privilegeDomain.getLowerFirstPlural()+" = "+this.roleDomain.getLowerFirstDomainName()+"Service.listActive"+this.roleDomain.getCapFirstDomainName()+this.privilegeDomain.getCapFirstPlural()+"Using"+this.roleDomain.getCapFirstDomainName()+"Id("+this.roleDomain.getLowerFirstDomainName()+".get"+this.roleDomain.getDomainId().getCapFirstFieldName()+"());"));
		sList.add(new Statement(81000L,4,"for ("+this.privilegeDomain.getCapFirstDomainNameWithSuffix()+" "+this.privilegeDomain.getLowerFirstDomainName()+": "+this.privilegeDomain.getLowerFirstPlural()+") {"));
		sList.add(new Statement(82000L,5,this.privilegeDomain.getLowerFirstDomainName()+"NameList.add("+this.privilegeDomain.getLowerFirstDomainName()+"."+this.privilegeDomain.getDomainName().getGetterCallName()+"());"));
		sList.add(new Statement(83000L,4,"}"));
		sList.add(new Statement(84000L,3,"}"));
		sList.add(new Statement(85000L,1,""));
			
		sList.add(new Statement(86000L,3,"if("+this.roleDomain.getLowerFirstDomainName()+"Names==null || "+this.roleDomain.getLowerFirstDomainName()+"Names.isEmpty())"));
		sList.add(new Statement(87000L,3,"{"));
		sList.add(new Statement(88000L,4,this.roleDomain.getLowerFirstDomainName()+"Names.add(\"noAnyAuth\");"));
		sList.add(new Statement(89000L,3,"}"));
		sList.add(new Statement(90000L,3,""));
		sList.add(new Statement(91000L,3,"SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); //创建一个这样的对象，它是返回的类型的子类"));
		sList.add(new Statement(92000L,3,"info.setRoles("+this.roleDomain.getLowerFirstDomainName()+"Names);"));
		sList.add(new Statement(93000L,3,"info.addStringPermissions("+this.privilegeDomain.getLowerFirstDomainName()+"NameList);"));
		sList.add(new Statement(94000L,0,""));
		sList.add(new Statement(95000L,3,"return info;"));
		
		sList.add(new Statement(95100L,2,"} catch (Exception e) {"));
		sList.add(new Statement(95200L,3,"return null;"));
		sList.add(new Statement(95300L,2,"}"));

		sList.add(new Statement(96000L,1,"}"));
		sList.add(new Statement(97000L,0,"}"));
		return sList.getContent();
	}

	public Domain getUserDomain() {
		return userDomain;
	}

	public void setUserDomain(Domain userDomain) {
		this.userDomain = userDomain;
	}

	public Domain getRoleDomain() {
		return roleDomain;
	}

	public void setRoleDomain(Domain roleDomain) {
		this.roleDomain = roleDomain;
	}

	public Domain getPrivilegeDomain() {
		return privilegeDomain;
	}

	public void setPrivilegeDomain(Domain privilegeDomain) {
		this.privilegeDomain = privilegeDomain;
	}
}
